#437: canonical RuntimeRetention owner + log-retention alias + CLAUDE.md carveout#480
#437: canonical RuntimeRetention owner + log-retention alias + CLAUDE.md carveout#480loning wants to merge 4 commits into
Conversation
…覆盖 generated files+pending-events compaction+stale worktree;CLAUDE.md 加 #437 narrow carveout
|
质量 review:approve 从可读性和简单性角度看,这个 PR 没有必须阻塞的问题。 小备注:runtime retention 的摘要格式在 CLI summary 和 restart logging 里有两处相近拼接,但只有两处且不影响理解,未达到需要抽取的阈值。 ⟦AI:AUTO-LOOP⟧ |
|
架构审查结论:reject。 PR 新增的 #437 carveout 在 CLAUDE.md/SKILL/authorization mirror 里要求 这让实际 runtime authority 比新写入的 narrow allowlist 更宽,违反 PR 自己新增的 需要修正为:generated file deletion 也必须消费 planner proof,或通过同一共识路径收窄 CLAUDE.md/SKILL/authorization 文案,让授权和实现一致。建议同时补一条行为测试:没有 planner eligibility 的旧 generated file 必须保留。 ⟦AI:AUTO-LOOP⟧ |
|
测试视角结论:reject。
具体问题:
建议补 没有看到本 PR 新增 sleep/skip/manual 测试,也没有看到明显的 assertion loosening。 ⟦AI:AUTO-LOOP⟧ |
根因:reviewer artifact frontmatter 不带 head_sha,_review_evidence_from_artifact 取不到所审 head SHA → 所有 reviewing PR(#480/#473/#402)恒判 WAIT_OR_REDISPATCH:invalid_reviewer_evidence:missing_reviewed_head_sha,且 wakeup-plan 不自动重派 reviewer → review→merge headless 永久卡死(挡住发版)。 修法(codex hotfix worker 实现,controller 验证后提交): - controller_actions 派 reviewer 时取 headRefOid,缺则 fail-closed,注入权威 HEAD_SHA 进 rendered prompt。 - reviewer-{architect,tests,quality}.md frontmatter 写 head_sha: ${HEAD_SHA}。 - wakeup_runner._review_head_sha_for:artifact 缺 head_sha 时从 controller-rendered prompt/log 回收(不依赖 worker 自报,避免 markerless 覆辙);live-head 陈旧判定与 merge 真值表语义不变。 - wakeup_plan 为 missing/stale reviewer head 的 OPEN reviewing PR 投射可执行 dispatch_reviewers 自愈动作。 验证:controller 独立重跑 test_wakeup_runner+review_gate+wakeup_plan+controller_actions 293 通过、marker/prompt 合同 30 通过;review-gate 安全语义(stale head 仍不 merge)由 13 项 review-gate 测试锁住。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…merge 闭环 承接 r7:r7 让 reviewer 证据绑定 head_sha,但 wakeup_plan 投射的 review-evidence-redispatch 自愈动作被 closed-action-projection finalizer 强制 status_only(其 kind 不在 EXECUTABLE_ACTION_KINDS),runner 永不应用 → #480/#473/#402 缺 head 的 review 证据无法自动重派 → review_gate 恒 WAIT_OR_REDISPATCH → 并发耗干到 0。 修法(codex hotfix worker 实现,controller 验证后提交): - wakeup_plan EXECUTABLE_ACTION_KINDS 加 review-evidence-redispatch,finalizer 保留 runner authority 不再强制 status_only。 - controller_actions.dispatch_reviewers 读 stale_review_roles 只重派陈旧角色,且 _pending_review_spawn_exists 跳过已有在飞 dispatch-reviewers:<pr>:<role>:r1 intent(幂等不双派);仍走 r7 的 HEAD_SHA 注入,使重派 reviewer 的新证据 head-bound。 - merge-gate 真值表不变,仅让既有自愈动作可执行 + 定向到陈旧角色。 验证:controller 独立重跑 test_wakeup_plan+wakeup_runner+review_gate+controller_actions 295 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ady PR headless merge,backlog 能 drain 根因(已核实):wakeup_plan 每 tick 把 SPAWN actions(implement intent + design-consensus #495/#496/#490/#491/#418,index 0-5)排在 lifecycle review_gate(#480/#473/#402,index 6-8)之前;run_once 旧逻辑 `if applied_spawns>0 and not is_spawn_action: break` → 只要派了任一 spawn,首个 lifecycle 即 break 整 tick。design-consensus 几乎总有 spawn 活 → review_gate/merge 永远 starve → #473(approve/approve/comment → MERGE_WITH_COMMENTS,MERGEABLE+CI 绿)永不 merge,active 数永不下降。 修法(最小,核心 dispatch loop): - 引入 consumes_spawn_budget = is_spawn_action or _uses_spawn_budget(action);超 budget 时 `continue`(不 break)以便仍能抵达后续 drain-only lifecycle。 - _uses_spawn_budget:dispatch_reviewers=True、review_gate 仅当决策为 FIX(会派 fix worker)=True;否则 review_gate(MERGE/MERGE_WITH_COMMENTS)、close 等 drain-only=False → 不占 spawn budget、floor 填满后仍被评估执行。 - 保留 r6 的 spawn launch-failure break/retry 与 dispatch_design_consensus no-intents skip-and-continue;真值表/head-binding/CI-green/mergeable 安全语义不变。 结果:每 tick 既用 spawn 填满 floor,又评估 merge/close 等 drain-only lifecycle,backlog 能 drain。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+wakeup_plan+controller_actions+pr_checks 309 通过;新增 test_wakeup_runner_lifecycle_review_gate_not_starved_after_spawn_batch。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… malformed — review→merge 根因 根因(实测确认):_run_command 对所有 gh 命令在 full[1:1] 插 --repo(子命令之前)。gh 不接受 --repo 作 pre-subcommand 全局 flag,且 gh api 根本不吃 --repo(repo 在 URL):`gh --repo O/R api repos/O/R/pulls/473` → rc=1 "unknown flag: --repo"。于是 wakeup-runner 的每个 gh 调用都 malformed:CI 读(PrChecksProjection(runner=_run_command) 的 gh api pulls/check-runs)→ ci_unavailable:pull_api_failure;mergeability(gh pr view)→ mergeability_unavailable;live-state 等同理。→ review gate 永远读不到 CI/mergeable → #473(approve/approve/comment=MERGE_WITH_COMMENTS,绿)、#402、#480 永不 headless 落地。r11 的 retry 只是重复同一 malformed 命令。直连 PrChecksProjection()/直连 gh 用的是 plain default runner(无注入)所以正常,掩盖了 bug。 最小修法:_run_command 仅对 `gh pr`/`gh issue` 注入 --repo,且放在子命令(及其 verb)之后的合法位置;`gh api` 完全不动;绝不 pre-subcommand 注入;已存在 --repo 则不重复。 验证:controller 独立重跑 test_wakeup_runner+review_gate+review_gate_e2e+pr_checks+wakeup_plan+controller_actions 312 通过;新增 argv-shape 测试 + e2e(stub subprocess.run 拒绝 malformed `gh --repo ... api`,ready PR 仍 merge)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Quality review approves PR 480TL;DR
详细说明重点看了 这个 skill-private cleanup 的主实现、 这个旧命令兼容入口、 的命令注册, 以及 的调用点。新代码把文件清理、pending-events 原地压缩、planner-proven worktree 清理拆成私有 helper, 每个函数尺寸和分支数都在可读范围内。 只是兼容别名, 没保留第二套清理逻辑; 把 注册为 canonical command, 复用同一个 handler; 在 daemon freshness checks 前调用 。这些路径都有对应测试锁住, 没发现新死代码、单实现多余抽象、无意义注释或离题改动。默认 , diff 里也没有新增 source-code 自文档注释。 📎 完整 codex 原始输出(存档备查)pr: 480
|
🤖 架构审查结论: rejectTL;DR
详细说明
具体证据: 修复路径很窄:让 generated-file cleanup 也消费 durable planner proof,并补测试证明“old generated file without planner proof is kept”;或者重新收窄/改写 #437 授权文本,但那需要和当前 carveout 同等级的共识与 source-regression。 📎 完整 codex 原始输出(存档备查)pr: 480
|
🤖 Quality review approves PR 480TL;DR
详细说明重点看了
📎 完整 codex 原始输出(存档备查)pr: 480
|
🤖 Tests review: reject,RuntimeRetention 删除保护缺测试TL;DR
详细说明
这属于 net-new destructive local-GC authority 的覆盖缺口,不是 nice-to-have。目标修复很小: 在 📎 完整 codex 原始输出(存档备查)---
pr: 480
role: tests
head_sha: 9c052577d132e72c1acc0642a6192a09c488c220
verdict: reject
---
## Verdict
Reject: the new RuntimeRetention tests cover the happy worktree-removal path, but they do not cover the dirty/ahead git recheck branches that prevent destructive `git worktree remove`.
## Evidence
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:186` and `:189` add the real safety rechecks before deletion: `git status --porcelain` must be clean and `git rev-list --count @{upstream}..HEAD` must not report local-ahead commits. These are net-new branches on a destructive cleanup path.
- `skills/codex-refactor-loop/scripts/test_runtime_retention.py:121` only exercises one eligible clean worktree and one planner-proof-false skip. Its fake runner always returns clean status and `0` ahead for the eligible worktree, so no test proves RuntimeRetention skips `git worktree remove` when the local recheck reports dirty files or ahead commits.
- Positive coverage is otherwise present: generated-file TTL deletion, symlink/FIFO preservation, same-inode pending-event compaction, host opt-in/noop behavior, CLI summary, log-retention aliasing, command authority source-regression, and runtime-exception source-regression are covered. Targeted PR-head verification passed with `cd skills/codex-refactor-loop/scripts && python3 -m unittest test_runtime_retention.py test_log_retention.py test_cli_command_router.py test_runtime_exception_authorization_sources.py` (`68 tests`, OK).
## What would change your verdict (only if comment or reject)
Add behavior tests in `test_runtime_retention.py` that create planner-eligible stale worktree entries and assert `git worktree remove` is not invoked when `git status --porcelain` returns output, when the status command fails, when `rev-list --count @{upstream}..HEAD` returns a positive count, and ideally when the worktree path is missing. These should assert `removed_worktrees == 0` and no prune/remove commands were issued for the blocked worktree.
⟦AI:AUTO-LOOP⟧
REVIEW_DONE:480:tests:reject⟦AI:AUTO-LOOP⟧ |
🤖 Tests review 结论: rejectTL;DR
详细说明
阻塞点在 需要补的测试很具体: 复用现有 fake 📎 完整 codex 原始输出(存档备查)pr: 480
|
🤖 架构审查结论: rejectTL;DR
详细说明
阻塞条款来自 📎 完整 codex 原始输出(存档备查)---
pr: 480
role: architect
head_sha: 9c052577d132e72c1acc0642a6192a09c488c220
verdict: reject
---
## Verdict
reject: RuntimeRetention introduces silent fail-closed/skip paths, which violates the repository requirement that failures, skips, and fail-closed decisions be diagnosable.
## Evidence
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:92`: `_delete_generated_files()` catches `OSError` and silently keeps the file. This is a cleanup skip/failure with no target id or reason, violating `CLAUDE.md` 工程约定: “任何错误、失败、fail-closed、skip、WAIT、budget 耗尽、分支不可达都必须抛出异常或写一条**可诊断、可 grep 的单行日志**(含目标 id、原因、关键计数),让问题在外部状态面立即可见。**禁止**空 `except`/`except: pass`、裸吞错、静默 `continue`/`return`、不记原因的跳过。”
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:100`: `_compact_pending_events()` swallows `OSError` and returns `False`, making event-log compaction failure indistinguishable from “not needed”. Same `CLAUDE.md` clause applies because this is a fail-closed/skip path without a diagnosable reason.
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:137`: `_read_retention_plan()` catches `OSError` and `JSONDecodeError` and returns an empty plan. That silently disables stale worktree cleanup even when the durable plan exists but is unreadable/corrupt, again violating the same `CLAUDE.md` diagnostic logging clause.
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:123`: stale worktree candidates rejected by `_eligible_worktree_path()` or `_git_verification_passes()` are skipped with no per-worktree reason. The #437 carveout in `CLAUDE.md` says RuntimeRetention may remove only planner-proven stale worktrees, and the general logging clause requires skipped/fail-closed worktree candidates to expose a grep-able reason.
## What would change your verdict
Add a narrow diagnostic surface to RuntimeRetention so every failure/skip/fail-closed branch writes or returns a single-line reason containing the affected path/worktree and cause, then ensure `main()` and `restart-daemons` surface those reasons. Do not widen the #437 allowlist or add a durable archive/index fact source; this can be a bounded warning list/count in the existing summary/log output.
⟦AI:AUTO-LOOP⟧
REVIEW_DONE:480:architect:reject⟦AI:AUTO-LOOP⟧ |
🤖 Quality review: reject, retention failure log loses the reasonTL;DR
详细说明是本 PR 新增的本地 runtime 清理入口, 会删除 skill-private generated files, 也可能按 plan 移除 stale worktree。 现在 catch 住所有 , 但 只输出 , 没有 之类的异常 detail。结果是 cleanup 失败、path guard 失败、git recheck 失败等都会变成同一行日志, 排查时没有目标原因。 建议和旁边 的写法一致: 后在同一行 warning 中包含 。这个改动很小, 不改变控制流, 但能让失败日志可 grep、可诊断。 📎 完整 codex 原始输出(存档备查)pr: 480
|
🤖 Quality review: reject, retention failure log loses the reasonTL;DR
详细说明上一条同标题评论的正文被 shell 反引号展开破坏了, 以这条为准。 建议和旁边 📎 完整 codex 原始输出(存档备查)pr: 480
|
…ase) # Conflicts: # CLAUDE.md # skills/codex-refactor-loop/scripts/test_comment_monitor.py # skills/codex-refactor-loop/scripts/test_log_retention.py # skills/codex-refactor-loop/scripts/test_restart_daemons.py # skills/codex-refactor-loop/scripts/test_runtime_exception_authorization_sources.py # skills/codex-refactor-loop/scripts/test_skill_reference_anchors.py
🤖 架构审查结论:reject,RuntimeRetention 仍有静默 skipTL;DR
详细说明这轮复审看的是 head 这违反 📎 完整 codex 原始输出(存档备查)---
pr: 480
role: architect
head_sha: 5e5bb1e3d2a03208e2cd8ff0652456b6eef36c4e
verdict: reject
---
## Verdict
reject: RuntimeRetention still introduces silent fail-closed/skip paths, so merge would regress the CLAUDE.md diagnostic contract.
## Evidence
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:92`: `_delete_generated_files()` catches `OSError` and silently increments `kept`, with no path/reason in stdout, stderr, or returned diagnostics. This violates `CLAUDE.md` 工程约定: “任何错误、失败、fail-closed、skip、WAIT、budget 耗尽、分支不可达都必须抛出异常或写一条**可诊断、可 grep 的单行日志**(含目标 id、原因、关键计数),让问题在外部状态面立即可见。**禁止**空 `except`/`except: pass`、裸吞错、静默 `continue`/`return`、不记原因的跳过。”
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:100`: `_compact_pending_events()` catches `OSError` and returns `False`, making event-log read failure indistinguishable from “compaction not needed”. Same `CLAUDE.md` clause applies because this is a fail-closed runtime maintenance skip without a diagnosable line.
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:137`: `_read_retention_plan()` catches `OSError` / `JSONDecodeError` and returns an empty plan, silently disabling stale worktree cleanup when the plan is unreadable or corrupt. Same `CLAUDE.md` clause applies because malformed planner proof must be visible, not converted to “no work”.
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/runtime_retention.py:123` and `:126`: stale worktree candidates rejected by `_eligible_worktree_path()` or `_git_verification_passes()` are skipped with no worktree id and no gate reason. The new #437 carveout in `CLAUDE.md` authorizes only planner-proven local GC, and the general logging clause requires skipped/fail-closed candidates to expose a grepable reason.
## What would change your verdict
Add a narrow diagnostic surface to `RuntimeRetention` so every failure/skip/fail-closed branch either raises a specific exception or emits/returns a single-line reason containing the affected path/worktree and cause, then make `main()` and `restart-daemons` surface those reasons. Keep the #437 allowlist narrow: no archive/index durable fact source, no new GitHub write, and no generic cleanup framework.
⟦AI:AUTO-LOOP⟧
REVIEW_DONE:480:architect:reject⟦AI:AUTO-LOOP⟧ |
🤖 测试审查结论: rejectTL;DR
详细说明我在提取出的 PR head 上跑了 , 结果 9 个测试中 2 个失败。失败点是 把测试用的 和 写进 , 但当前 合同明确不读取这个 legacy path。 启动 CLI 时也没有设置 , 所以 CLI 按预期 fail closed, 报 。 修法很窄: 测试 fixture 应该创建 , 并在 的 env 中传 。我没有看到新增 /skip/manual marker, 也没有看到断言被明显放松;主行为覆盖方向是对的,但新增测试必须先能在 PR head 上绿。 📎 完整 codex 原始输出(存档备查)default raw artifact: ---
pr: 480
role: tests
head_sha: 5e5bb1e3d2a03208e2cd8ff0652456b6eef36c4e
verdict: reject
---
## Verdict
Reject: the new RuntimeRetention CLI tests are not passing on the PR head because the fixture uses the legacy `.refactor-loop/host.env` path that `LoopContext` explicitly refuses to read.
## Evidence
- `skills/codex-refactor-loop/scripts/test_runtime_retention.py:33` writes `REPO_ROOT` and `RUNTIME_RETENTION_ENABLE` to `.refactor-loop/host.env`, but `skills/codex-refactor-loop/scripts/codex_refactor_loop/context.py:158` says legacy `.refactor-loop/host.env` is not read.
- `skills/codex-refactor-loop/scripts/test_runtime_retention.py:49` runs the CLI with only `PATH` and `PYTHONPATH`, so `CONSENSUS_RND_HOST_ENV` is absent. On an extracted PR-head tree, `python3 -m unittest skills/codex-refactor-loop/scripts/test_runtime_retention.py` fails `test_default_disabled_noops_even_when_old_files_exist` and `test_cli_uses_host_env_and_reports_summary` with `FATAL: REPO_ROOT is unset; ... legacy .refactor-loop/host.env is not read`.
- I did not find added `sleep`/skip/manual-test markers or assertion loosening in the Python diff. The behavior tests otherwise cover delete scope, opt-in noop, symlink/FIFO preservation, pending-event compaction, worktree planner proof plus git recheck, command registration, aliasing, and authorization source-regression.
## What would change your verdict
Fix the `RuntimeRetentionBehaviorTests` fixture to create a host-owned `.config/consensus-rnd/host.env` and pass `CONSENSUS_RND_HOST_ENV=.config/consensus-rnd/host.env` in `run_cli`, then rerun `python3 -m unittest skills/codex-refactor-loop/scripts/test_runtime_retention.py`.
⟦AI:AUTO-LOOP⟧
REVIEW_DONE:480:tests:reject⟦AI:AUTO-LOOP⟧ |
🤖 测试审查结论: reject(更正版)TL;DR
详细说明我在提取出的 PR head 上跑了 修法很窄: 测试 fixture 应该创建 📎 完整 codex 原始输出(存档备查)---
pr: 480
role: tests
head_sha: 5e5bb1e3d2a03208e2cd8ff0652456b6eef36c4e
verdict: reject
---
## Verdict
Reject: the new RuntimeRetention CLI tests are not passing on the PR head because the fixture uses the legacy `.refactor-loop/host.env` path that `LoopContext` explicitly refuses to read.
## Evidence
- `skills/codex-refactor-loop/scripts/test_runtime_retention.py:33` writes `REPO_ROOT` and `RUNTIME_RETENTION_ENABLE` to `.refactor-loop/host.env`, but `skills/codex-refactor-loop/scripts/codex_refactor_loop/context.py:158` says legacy `.refactor-loop/host.env` is not read.
- `skills/codex-refactor-loop/scripts/test_runtime_retention.py:49` runs the CLI with only `PATH` and `PYTHONPATH`, so `CONSENSUS_RND_HOST_ENV` is absent. On an extracted PR-head tree, `python3 -m unittest skills/codex-refactor-loop/scripts/test_runtime_retention.py` fails `test_default_disabled_noops_even_when_old_files_exist` and `test_cli_uses_host_env_and_reports_summary` with `FATAL: REPO_ROOT is unset; ... legacy .refactor-loop/host.env is not read`.
- I did not find added `sleep`/skip/manual-test markers or assertion loosening in the Python diff. The behavior tests otherwise cover delete scope, opt-in noop, symlink/FIFO preservation, pending-event compaction, worktree planner proof plus git recheck, command registration, aliasing, and authorization source-regression.
## What would change your verdict
Fix the `RuntimeRetentionBehaviorTests` fixture to create a host-owned `.config/consensus-rnd/host.env` and pass `CONSENSUS_RND_HOST_ENV=.config/consensus-rnd/host.env` in `run_cli`, then rerun `python3 -m unittest skills/codex-refactor-loop/scripts/test_runtime_retention.py`.
⟦AI:AUTO-LOOP⟧
REVIEW_DONE:480:tests:reject⟦AI:AUTO-LOOP⟧ |
🤖 Quality review 拦截: authority token 与新测试夹具不一致TL;DR
详细说明我没有发现
📎 完整 codex 原始输出(存档备查)---
pr: 480
role: quality
head_sha: 5e5bb1e3d2a03208e2cd8ff0652456b6eef36c4e
verdict: reject
---
## Verdict
Reject because the PR leaves the public command authority catalog internally inconsistent and adds runtime-retention tests that cannot run under the current host.env locator contract.
## Evidence
- `skills/codex-refactor-loop/scripts/codex_refactor_loop/cli.py:62` still declares `COMMANDS["revive-implements"].authority` as `("delete-log",)`, while `skills/codex-refactor-loop/scripts/test_cli_command_router.py:24` replaces the closed authority token catalog with `delete-runtime`; the touched command router test fails with `('delete-log',)` outside `ALL_AUTHORITY_TOKENS`. This is not a naming nit: the public authority fact source no longer has a closed token vocabulary.
- `skills/codex-refactor-loop/scripts/test_runtime_retention.py:33` writes the fixture host env to `.refactor-loop/host.env`, but `run_cli()` at `skills/codex-refactor-loop/scripts/test_runtime_retention.py:49` does not set `CONSENSUS_RND_HOST_ENV` or source `REPO_ROOT`; both `test_default_disabled_noops_even_when_old_files_exist` and `test_cli_uses_host_env_and_reports_summary` fail with `FATAL: REPO_ROOT is unset... legacy .refactor-loop/host.env is not read`.
## What would change your verdict (only if comment or reject)
Change `revive-implements` to a valid closed authority token or keep `delete-log` in the catalog if it remains intentional, then update `test_runtime_retention.py` to create a host-owned `.config/consensus-rnd/host.env` and pass `CONSENSUS_RND_HOST_ENV` in `run_cli()` like `test_log_retention.py` already does. Re-run the narrow tests from the PR head.
⟦AI:AUTO-LOOP⟧
REVIEW_DONE:480:quality:reject⟦AI:AUTO-LOOP⟧ |
🤖 关闭本 PR(stale + 实现有真实缺陷)— #437 转回 design-solving 重做本 PR 是 #437(.refactor-loop 历史生成物/陈旧 worktree 的有界清理机制)的 stale-base 恢复尝试,但经 review + CI 确认实现有真实缺陷,非单纯 stale 噪音:
结论:磨这个又 stale 又有设计缺陷的低价值 PR ROI 太低。关闭本 PR,把 #437 转回 ⟦AI:AUTO-LOOP⟧ |
摘要
解决设计 issue #437(r4 consensus:structural)。
log-retention被扩义承载 runtime 生成物/pending-events/stale worktree 清理,operational name 与授权边界漂移。RuntimeRetentionowner;log-retention降为一版 compatibility alias;清理覆盖 host-opt-in generated files + pending-events same-inode compaction + planner 证明 stale 的.worktreesremove/prune;CLAUDE.md 加 .refactor-loop 历史生成物与陈旧 worktree 的有界清理机制 #437 narrow local-GC carveout(无 GitHub/git lifecycle authority)。范围
新 runtime_retention.py + cli/restart + log-retention alias + CLAUDE.md/SKILL.md carveout + 新 test_runtime_retention.py(+224)+ source-regression。consensus 授权 CLAUDE.md 变更。
Closes #437
🤖 Auto-loop / codex-refactor-loop
⟦AI:AUTO-LOOP⟧